package thread;

/**
 * 同步块
 * 语法:
 * synchronized(同步监视器对象){
 * 需要同步执行的代码片段
 * }
 * <p>
 * 使用同步块可以更精准的锁定需要多个线程同步执行的代码片段，有效的缩小排队范围可以在保证并发安全的
 * 前提下提高并发效率.
 */
public class SyncDemo2 {
    public static void main(String[] args) {
        Shop sp = new Shop();
        Thread p1 = new Thread() {
            public void run() {
                sp.buy();
            }
        };
        Thread p2 = new Thread() {
            public void run() {
                sp.buy();
            }
        };
        p1.start();
        p2.start();

    }
}

class Shop {
    /**
     * synchronized 同步方法.
     * -------在方法上使用synchronized时，同步监视器对象就是当前方法所属对象，即:this
     * -------static方法:没有隐士this.
     * -----------------当静态方法使用synchronized修饰后，该方法一定具有同步效果.
     */
    //将多线程并发操作改为同步排队操作可能有效解决多线程并发安全问题.
    //public synchronized void buy(){}
    public void buy() {
        try {
            Thread t = Thread.currentThread();//获取运行buy方法的线程
            System.out.println(t.getName() + ":正在挑衣服...");
            Thread.sleep(5000);
            /** synchronized (this) {} : 同步块 */
            /*
                使用同步块时要在()中指定同步监视器对象，该对象可以是Java中任何的实例，但是
                必须保证多个需要同步执行该代码块的线程看到的这个同步监视器对象是同一个才可以.
             */
            synchronized (this) {//--------需要同步执行的代码片段
//            synchronized (new Object()) {//new Object : 没有解决多线程并发安全问题.
                System.out.println(t.getName() + ":正在试穿...");
                Thread.sleep(5000);
            }

            System.out.println(t.getName() + ":结账离开！");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

}